<!DOCTYPE html>
<html>
<head>
<style>
#graph {
	width: 100%;
	height: 100%;
}

#gameArea {
	position: absolute;
	left: 50%;
	top: 50%;
}

</style>
</head>
<body>
<noscript>This page requires javascript to function</noscript>
<div id="gameArea">
	<canvas id="graph">
		Your browser doesn't support canvas.
	</canvas>
</div>
<script>
var canvas = document.getElementById("graph");
var c = canvas.getContext("2d");
var gistemp = [-20, -12, -15, -18, -26, -24, -23, -31, -19,  -9, -32, -26, -30, -35, -32, -24, -17, -17, -30, -19, -14, -20, -30, -36, -43, -29, -25, -41, -42, -46, -45, -44, -40, -38, -22, -16, -35, -43, -31, -28, -26, -20, -28, -25, -23, -21,  -8, -17, -16, -30, -11,  -6, -10, -24,  -9, -14, -10,   4,   6,   1,   7,   8,   5,   6,  14,   1,  -8,  -4, -10, -11, -19,  -6,   2,   9, -11, -12, -18,   4,   5,   3,  -4,   5,   4,   7, -20, -10,  -4,  -1,  -5,   6,   4,  -7,   2,  16,  -7,  -1, -12,  15,   5,  12,  23,  28,   9,  27,  12,   8,  14,  28,  35,  24,  39,  38,  19,  21,  28,  43,  32,  45,  61,  40,  40,  52,  61,  60,  51,  65,  59,  62,  49,  59,  66,  55,  57,  60];

var trend_endindex = gistemp.length - 16;
var trend_startindex = trend_endindex - 22;

var trend = findLineByLeastSquares(gistemp);

var trend_drag = "";

function getMousePos(evt) {
	var rect = canvas.getBoundingClientRect();
	return {
		x: evt.clientX - rect.left,
		y: evt.clientY - rect.top
	};
}
function Resize() {
	var gameArea = document.getElementById('gameArea');
    var widthToHeight = 4 / 3;
    var newWidth = window.innerWidth;
    var newHeight = window.innerHeight;
    var newWidthToHeight = newWidth / newHeight;
    
    if (newWidthToHeight > widthToHeight) {
        newWidth = newHeight * widthToHeight;
        gameArea.style.height = newHeight + 'px';
        gameArea.style.width = newWidth + 'px';
    } else {
        newHeight = newWidth / widthToHeight;
        gameArea.style.width = newWidth + 'px';
        gameArea.style.height = newHeight + 'px';
    }
    
    gameArea.style.marginTop = (-newHeight / 2) + 'px';
    gameArea.style.marginLeft = (-newWidth / 2) + 'px';

    canvas.width = newWidth;
    canvas.height = newHeight;

	DrawGraph();
}

function MouseDown(event) {
	var mouse = getMousePos(event);
	if (Math.abs(indexToPixel(trend_startindex) - mouse.x) < 20) {trend_drag = "start";}
	else {
		if (Math.abs(indexToPixel(trend_endindex) - mouse.x) < 20) {trend_drag = "end";}
	}
}

function MouseUp(event) {
	trend_drag = "";
}

function MouseMove(event) {
	if (trend_drag != "") {
		var mouse = getMousePos(event);

		if (trend_drag == "start") {
			trend_startindex = pixelToIndex(mouse.x);
			if (trend_startindex > trend_endindex) {trend_endindex = trend_startindex;}
		}

		if (trend_drag == "end") {
			trend_endindex = pixelToIndex(mouse.x);
			if (trend_startindex > trend_endindex) {trend_startindex = trend_endindex;}
		}
		
		trend = findLineByLeastSquares(gistemp);

		DrawGraph();
	}
}

function tempToPixel(index, temp) {
	return {
		x: indexToPixel(index),
		y: -temp * canvas.height / 200.0 + canvas.height / 2.0
	};
}

function indexToPixel(index) {
	return index * canvas.width / gistemp.length;
}

function pixelToIndex(x) {
	x /= canvas.width;
	x *= gistemp.length;

	return Math.round(x);
}

function DrawGraph() {
	var index;
	var pix = tempToPixel(0, gistemp[0]);

	c.fillStyle = "white";
	c.fillRect(0, 0, canvas.width, canvas.height);

	c.strokeStyle = "black";

	c.beginPath();
	c.moveTo(pix.x, pix.y);
	
	for (index = 1; index < gistemp.length; ++index) {
		var pix = tempToPixel(index, gistemp[index]);
		c.lineTo(pix.x, pix.y);
	}

	c.stroke();

	c.strokeStyle = "gray";
	c.beginPath();

	c.moveTo(indexToPixel(trend_startindex), 0);
	c.lineTo(indexToPixel(trend_startindex), canvas.height);

	c.moveTo(indexToPixel(trend_endindex), 0);
	c.lineTo(indexToPixel(trend_endindex), canvas.height);

	c.stroke();
	
	c.strokeStyle = "red";
	c.beginPath();
	
	drawTrend(c, 0, trend_startindex);
	drawTrend(c, 2*trend[2], trend_endindex);
	drawTrend(c, -2*trend[2], trend_endindex);
	
	c.stroke();
	
	c.strokeStyle = "blue";
	c.beginPath();
	
	drawFlat(c, 0, trend_endindex);
	drawFlat(c, 2*trend[2], trend_endindex);
	drawFlat(c, -2*trend[2], trend_endindex);
	
	c.stroke();
}

function drawTrend(c, offset, start) {
	pix = tempToPixel(start, calcTrend(start) + offset);
	c.moveTo(pix.x, pix.y);
	
	pix = tempToPixel(gistemp.length - 1, calcTrend(gistemp.length - 1) + offset);
	c.lineTo(pix.x, pix.y);
}

function drawFlat(c, offset, start) {
	pix = tempToPixel(start, calcTrend(start) + offset);
	c.moveTo(pix.x, pix.y);
	
	pix = tempToPixel(gistemp.length - 1, calcTrend(start) + offset);
	c.lineTo(pix.x, pix.y);
}

function calcTrend(x) {
	return x * trend[0] + trend[1];
}

function findLineByLeastSquares(values_y) {
    var sum_x = 0; var sum_y = 0;
    var sum_yy = 0; var sum_xx = 0;
    var sum_xy = 0; var count = 0;

    var x = 0; var y = 0;
    var values_length = values_y.length;
    if (values_length === 0) {return [0, 0];}

    for (var v = trend_startindex; v < values_length && v < trend_endindex; v++) {
        x = v; y = values_y[v];
        sum_x += x; sum_y += y;
        sum_xx += x*x; sum_yy += y*y;
		sum_xy += x*y;
        count++;
    }

    var m = (count*sum_xy - sum_x*sum_y) / (count*sum_xx - sum_x*sum_x);
    var b = (sum_y/count) - (m*sum_x)/count;
	var stddev = 0;
	
	var ssyy = sum_yy - (sum_y*sum_y / count);
	var ssxy = sum_xy - (sum_y*sum_x / count);
	
	if (count > 2) {
		stddev = Math.sqrt(Math.sqrt((ssyy - b * ssxy) / (count - 2)))
	}

    return [m, b, stddev];
}

canvas.addEventListener("mousedown", MouseDown, false);
canvas.addEventListener("mouseup", MouseUp, false);
canvas.addEventListener("mousemove", MouseMove, false);

window.addEventListener("resize", Resize, false);
window.addEventListener("orientationchange", Resize, false);

Resize();
</script>
</body>
<html>